/**
 * @file   FormItem.java
 * @author Enrique Madrid <e.madrid@lpcsite.com>
 * @date   Wed Aug  8 03:32:01 2007
 * 
 * @brief  Item de un nodo.
 * 
 * 
 */
package sim.forms;

import sim.framework.*;
import sim.utils.parser.*;
import sim.utils.Utils;
import sim.framework.gui.*;

public final class FrmItem implements ParserScan {

    public static final String STR_TOKEN = ";";
    public static final byte[] TOKEN = STR_TOKEN.getBytes();

    private static final int TOKEN_ITEM = Utils.TOKEN_PIPE;
    private static final int TOKEN_CODE = Utils.TOKEN_COLON;

    protected static final String JOCKER = "*";

    private static final int HIT_ITEM = 1;
    private static final int HIT_NODE = 2;

    protected String m_Code = null;	// Código del Item (Valor a devolver, opcional).
    protected String m_Desc = null;	// Descripción del Item (Valor a comparar, obligatorio)
    protected int m_Node = FrmNode.NODE_NEXT;	// Nodo asociado a este Item (opcional).
    protected boolean m_Selected = false; // 
    protected int m_Id;

    private String m_Encoding;

    private FrmItem(final String encoding) {
	m_Encoding = encoding;
    }

    protected static FrmItem create(final String encoding, FrmNode node, byte[] line, int start, int length) {
	FrmItem item;
	Parser p;
	
	item = new FrmItem(encoding);
	p = new Parser(item, Utils.TOKEN, TOKEN_ITEM, 1, Parser.FORWARD);
	if (!p.scan(line, start, length, node)) {
	    item = null;
	}
	
	return item;
    }

    /** 
     * Devuelve la opción que representa este item.
     *
     * @return Devuelve el código de la opción si existe; en caso contrario, devuelve la descripción.
     */
    protected String getOption() {
	return ((m_Code != null) ? m_Code : m_Desc);
    }

    public boolean parserHit(int hit, final byte[] line, int start, int length, Object something) {
	int eureka;
	boolean ret;
	FrmNode node;
	ParserDate pd;

	ret = true;
	switch(hit) {
	case FrmItem.HIT_ITEM:
	    // Código del item. (Puede no existir).
	    eureka = Utils.memmem(line, start, length, Utils.TOKEN, FrmItem.TOKEN_CODE, 1);
	    if (eureka > -1) {
		m_Code = Utils.decoding(line, start, eureka - start, m_Encoding);
		length = length - (eureka + 1 - start) ;
		start = eureka + 1;
	    } 
	    // Descripción del item. (obligatorio)
	    if (length > 0) {
		node = (FrmNode)something;
		switch (node.m_Type) {
		case GuiCtrl.DATE:
		case GuiCtrl.DAY:
		    pd = new ParserDate();
		    pd.scanDay(line, start, length);
		    m_Desc = Integer.toHexString(pd.getDayInSeconds());
		    break;
		case GuiCtrl.TIME:
		    pd = new ParserDate();
		    pd.scanHour(line, start, length);
		    m_Desc = Integer.toHexString(pd.getHourInSeconds());
		    break;
		default:
		    m_Desc = Utils.decoding(line, start, length, m_Encoding);
		}
	    }
	    ret = (m_Desc != null);
	    break;
	case FrmItem.HIT_NODE:
	    // Nodo asociado a este Item.
	    m_Node = Utils.memtoul(line, start, length, 10);
	    break;
	}
	return ret;
    }


    public boolean parserEnd(boolean cancel) {
	// Aqui se debe validar si uno o más campos estraidos en parserHit() son
	// son incompatibles, no se complementan, o entran en conflicto. De
	// momento no hay otra validación.
	return true;
    }
}

